package cn.imvc.app.models;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.imvc.app.controllers.goods.GoodsController;
import cn.imvc.app.entities.Area;
import cn.imvc.app.entities.Goods;
import cn.imvc.app.entities.GoodsCountry;
import cn.imvc.app.entities.GoodsOrder;
import cn.imvc.app.entities.GoodsSku;
import cn.imvc.app.entities.Orders;
import cn.imvc.app.entities.StorageOrder;
import cn.imvc.app.repositories.GoodsCountryRepository;
import cn.imvc.util.BiService;
import cn.imvc.util.EncreptAndDecreptUtil;
import cn.imvc.util.HttpHelper;
import cn.imvc.util.RSAUtil;

@Service
public class BiOrderClientModelImpl implements BiOrderClientModel{

	@Autowired
	BiService biService;
	@Autowired
	OrdersModel ordersModel;
	@Autowired
	StorageOrderModel storageOrderModel;
	@Autowired
	AreaModel areaModel;
	@Autowired
	GoodsCountryRepository countryRepository;
	
	public String updatePushOrder(int storageOrderId) throws Exception {
		StorageOrder storageOrder = storageOrderModel.get(storageOrderId);
		Orders orders = storageOrder.getOrder();
		// 初始化企业信息
		HashMap<String, String> companyInfo = initCompanyInfo();
		// 准备订单信息
		String dataInfo = getOrderXmlStr(companyInfo,orders,storageOrder);
//		System.out.println("======订单数据:======\n" + dataInfo);
		// RSA加密
		String encryptDataInfo = EncreptAndDecreptUtil.encreptData(dataInfo,
				companyInfo.get("publicKey"));
//		System.out.println("======RSA加密后:======\n" + encryptDataInfo);
		// 32位MD5签名
		String signature = RSAUtil.getEncode32(encryptDataInfo);
//		System.out.println("======签名信息:======\n" + signature);
		// 生成请求报文
		String xml = generateXml(companyInfo, encryptDataInfo, signature);
		if(xml != null && xml.startsWith("错误")){
			return xml;
		}
		if(xml == null){
			return "错误：生成报关xml，失败";
		}
//		System.out.println("======最终报文数据:======\n" + xml);
		HashMap<String, String> map = new HashMap<String, String>();
		map.put("xml", xml);
		// 调用webservice服务
		String PostResult = HttpHelper.sendHttpPOSTRequest(biService.getPushOrderUrl(),	map);
		// 查看响应回执
//		System.out.println("======报文回执:======\n" + PostResult);
		return PostResult;
	}

	/**
	 * 准备企业信息
	 * 
	 * @return
	 */
	private HashMap<String, String> initCompanyInfo() {
		// 准备企业信息
		HashMap<String, String> companyInfo = new HashMap<String, String>();
		// 企业编号,E贸易中注册的编号
		companyInfo.put("companyCode", biService.getCompanyCode());
		// 企业名称,E贸易中注册的名称
		companyInfo.put("companyName", biService.getCompanyName());
		// 国检备案的企业编码
		companyInfo.put("ecCode", biService.getEcCode());
		// 国检备案的企业名称
		companyInfo.put("ecName", biService.getEcName());
		// 海关备案的企业编码
		companyInfo.put("cbeCode", biService.getCbeCode());
		// 海关备案的企业名称
		companyInfo.put("cbeName", biService.getCbeName());
		// 电商平台国检备案编码
		companyInfo.put("ecpCodeCiq", biService.getEcpCodeCiq());
		// 电商平台国检备案名称
		companyInfo.put("ecpNameCiq", biService.getEcpNameCiq());
		// 电商平台海关备案编码
		companyInfo.put("ecpCodeCus", biService.getEcpCodeCus());
		// 电商平台海关备案名称
		companyInfo.put("ecpNameCus", biService.getEcpNameCus());
		// 企业公钥串,由E贸易提供
		companyInfo
				.put("publicKey", biService.getPublicKey());
		// 企业key，由E贸易提供
		companyInfo.put("companyKey", biService.getCompanyKey());
		return companyInfo;
	}

	/**
	 * 生成请求报文数据
	 * 
	 * @param encryptDataInfo
	 * @return
	 */
	private String generateXml(HashMap<String, String> companyInfo,
			String encryptDataInfo, String signature) {
		StringBuffer xmlSb = new StringBuffer();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateNowStr = dateFormat.format(new Date());
		xmlSb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
		xmlSb.append("<Root>\n");
		xmlSb.append("	<PubInfo>\n");
		xmlSb.append("			<Version>1.0</Version>\n");
		xmlSb.append("			<CompanyCode>").append(companyInfo.get("companyCode"))
				.append("</CompanyCode>\n");
		xmlSb.append("			<Key>").append(companyInfo.get("companyKey"))
				.append("</Key>\n");
		xmlSb.append("			<MsgType>O</MsgType>\n");
		xmlSb.append("			<OptType>1</OptType>\n");
		xmlSb.append("			<Signature>").append(signature)
				.append("</Signature>\n");
		xmlSb.append("			<CreatTime>"+dateNowStr+"</CreatTime>\n");
		xmlSb.append("	</PubInfo>\n");
		xmlSb.append("	<DataInfo>").append(encryptDataInfo)
				.append("</DataInfo>\n");
		xmlSb.append("</Root>\n");
		return xmlSb.toString();
	}

	private String getOrderXmlStr(HashMap<String, String> companyInfo,Orders orders,StorageOrder storageOrder) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
		StringBuffer orderXmlSb = new StringBuffer();
		String[] pccArray = orders.getAddressId().split(",");
		Area province = areaModel.get(Integer.parseInt(pccArray[0]));
		Area city = areaModel.get(Integer.parseInt(pccArray[1]));
		Area country = areaModel.get(Integer.parseInt(pccArray[2]));
		int goodsCount = 0;
//		 = orders.getPayChannel()
		orderXmlSb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
		orderXmlSb.append("<Order>\n");
		orderXmlSb.append("<OrderHead>\n");
		orderXmlSb.append("<ecCode>").append(companyInfo.get("ecCode"))
				.append("</ecCode>\n");
		orderXmlSb.append("<cbeCode>").append(companyInfo.get("cbeCode"))
				.append("</cbeCode>\n");
		orderXmlSb.append("<ecName>").append(companyInfo.get("ecName"))
				.append("</ecName>\n");
		orderXmlSb.append("<cbeName>").append(companyInfo.get("cbeName"))
				.append("</cbeName>\n");
		orderXmlSb.append("<ecpCodeCiq>").append(companyInfo.get("ecpCodeCiq"))
				.append("</ecpCodeCiq>\n");
		orderXmlSb.append("<ecpCodeCus>").append(companyInfo.get("ecpCodeCus"))
				.append("</ecpCodeCus>\n");
		orderXmlSb.append("<ecpNameCiq>").append(companyInfo.get("ecpNameCiq"))
				.append("</ecpNameCiq>\n");
		orderXmlSb.append("<ecpNameCus>").append(companyInfo.get("ecpNameCus"))
				.append("</ecpNameCus>\n");
		orderXmlSb.append("<orderNo>"+storageOrder.getCode()+"</orderNo>\n");
		orderXmlSb.append("<charge>"+orders.getFreightAmount()+"</charge>\n");
		orderXmlSb.append("<goodsValue>"+orders.getGoodsAmount()+"</goodsValue>\n");
		orderXmlSb.append("<freight>"+storageOrder.getFreight()+"</freight>\n");
		orderXmlSb.append("<other></other>\n");
		orderXmlSb.append("<tax></tax>\n");
		orderXmlSb.append("<customer>"+orders.getMember().getTruename()+"</customer>\n");
		orderXmlSb.append("<shipper>"+biService.getShipper()+"</shipper>\n");
		orderXmlSb
				.append("<shipperAddress>"+biService.getShipperAddress()+"</shipperAddress>\n");
		orderXmlSb.append("<shipperTelephone>"+biService.getShipperTelephone()+"</shipperTelephone>\n");
		orderXmlSb.append("<shipperCountryCiq>156</shipperCountryCiq>\n");
		orderXmlSb.append("<shipperCountryCus>142</shipperCountryCus>\n");
		orderXmlSb.append("<consignee>"+orders.getName()+"</consignee>\n");
		orderXmlSb.append("<consigneeProvince>"+province.getName()+"</consigneeProvince>\n");
		orderXmlSb.append("<consigneeCity>"+city.getName()+"</consigneeCity>\n");
		orderXmlSb.append("<consigneeZone>"+country.getName()+"</consigneeZone>\n");
		orderXmlSb
				.append("<consigneeAddress>"+orders.getAddress()+"</consigneeAddress>\n");
		orderXmlSb
				.append("<consigneeTelephone>"+orders.getTelephone()+"</consigneeTelephone>\n");
		orderXmlSb.append("<consigneeCountryCiq>156</consigneeCountryCiq>\n");
		orderXmlSb.append("<consigneeCountryCus>142</consigneeCountryCus>\n");
		orderXmlSb.append("<idType>1</idType>\n");
		orderXmlSb.append("<idNumber>"+biService.getIdNumber()+"</idNumber>\n");
		orderXmlSb.append("<ieType>I</ieType>\n");
		orderXmlSb.append("<stockFlag>2</stockFlag>\n");
		orderXmlSb.append("<batchNumbers>xinghao"+dateFormat.format(new Date())+"</batchNumbers>\n");
		orderXmlSb.append("<totalLogisticsNo>35656458412</totalLogisticsNo>\n");
		orderXmlSb.append("<tradeCountryCiq>156</tradeCountryCiq>\n");
		orderXmlSb.append("<tradeCountryCus>142</tradeCountryCus>\n");
		orderXmlSb.append("<agentCodeCiq>"+biService.getAgentCodeCiq()+"</agentCodeCiq>\n");
		orderXmlSb.append("<agentCodeCus>"+biService.getAgentCodeCus()+"</agentCodeCus>\n");
		orderXmlSb.append("<agentNameCiq>"+biService.getAgentNameCiq()+"</agentNameCiq>\n");
		orderXmlSb.append("<agentNameCus>"+biService.getAgentNameCus()+"</agentNameCus>\n");
		orderXmlSb.append("<packageTypeCiq>4M</packageTypeCiq>\n");
		orderXmlSb.append("<packageTypeCus>2</packageTypeCus>\n");
		orderXmlSb.append("<modifyMark>1</modifyMark>\n");
		orderXmlSb.append("<note></note>\n");
		orderXmlSb.append("</OrderHead>\n");
		Iterator<GoodsOrder> iterator = storageOrder.getGoodsOrder().iterator();
		while (iterator.hasNext()) {
			GoodsOrder goodsOrder = (GoodsOrder) iterator.next();
			List<GoodsCountry> countries = countryRepository.getByGoodsId(goodsOrder.getGoods().getId());
			if(countries.isEmpty()){
				return "错误：商品"+goodsOrder.getName()+"没有维护生产国";
			}
			GoodsCountry goodsCountry = countries.get(0);
			orderXmlSb.append("<OrderList>\n");
			orderXmlSb.append("<itemNoCiq></itemNoCiq>\n");
			orderXmlSb.append("<itemNoCus></itemNoCus>\n");
			orderXmlSb.append("<goodsNo>xh"+goodsOrder.getGoodsSku().getId()+"</goodsNo>\n");
			orderXmlSb
					.append("<shelfGoodsName>"+goodsOrder.getName()+"</shelfGoodsName>\n");
			orderXmlSb.append("<goodsName></goodsName>\n");
			orderXmlSb.append("<describe></describe>\n");
			orderXmlSb.append("<codeTs></codeTs>\n");
			orderXmlSb.append("<ciqCode></ciqCode>\n");
			orderXmlSb.append("<goodsModel>"+goodsOrder.getSpec()+"</goodsModel>\n");
			orderXmlSb.append("<taxCode></taxCode>\n");
			orderXmlSb.append("<price></price>\n");
			orderXmlSb.append("<currencyCiq>156</currencyCiq>\n");
			orderXmlSb.append("<currencyCus>142</currencyCus>\n");
			orderXmlSb.append("<quantity>"+goodsOrder.getNum()+"</quantity>\n");
			goodsCount+=goodsOrder.getTotals();
			orderXmlSb.append("<priceTotal>"+goodsOrder.getTotals()+"</priceTotal>\n");
			orderXmlSb.append("<unitCiq>"+goodsCountry.getUnitId_g()+"</unitCiq>\n");
			orderXmlSb.append("<unitCus>"+goodsCountry.getUnitId_h()+"</unitCus>\n");
			orderXmlSb.append("<discount></discount>\n");
			orderXmlSb.append("<giftsFlag></giftsFlag>\n");
			orderXmlSb.append("<originCountryCiq>"+goodsCountry.getCountryId_g().getCode()+"</originCountryCiq>\n");
			orderXmlSb.append("<originCountryCus>"+goodsCountry.getCountryId_h().getCode()+"</originCountryCus>\n");
			orderXmlSb.append("<usage></usage>\n");
			orderXmlSb.append("<wasteMaterials>1</wasteMaterials>\n");
			orderXmlSb.append("<wrapTypeCiq></wrapTypeCiq>\n");
			orderXmlSb.append("<wrapTypeCus></wrapTypeCus>\n");
			orderXmlSb.append("<packNum>"+goodsOrder.getNum()+"</packNum>\n");
			orderXmlSb.append("</OrderList>\n");
		}
		
		orderXmlSb.append("<OrderPaymentLogistics>\n");
		orderXmlSb.append("<paymentCode>"+biService.getPaymentCode(orders.getPayChannel())+"</paymentCode>\n");
		orderXmlSb.append("<paymentName>"+biService.getPaymentName(orders.getPayChannel())+"</paymentName>\n");
		orderXmlSb.append("<paymentType></paymentType>\n");
		orderXmlSb.append("<paymentNo>"+orders.getPayCode()+"</paymentNo>\n");
		orderXmlSb.append("<logisticsCodeCiq>"+biService.getLogisticsCodeCiq()+"</logisticsCodeCiq>\n");
		orderXmlSb.append("<logisticsCodeCus>"+biService.getLogisticsCodeCus()+"</logisticsCodeCus>\n");
		orderXmlSb
				.append("<logisticsNameCiq>"+biService.getLogisticsNameCiq()+"</logisticsNameCiq>\n");
		orderXmlSb
				.append("<logisticsNameCus>"+biService.getLogisticsNameCus()+"</logisticsNameCus>\n");
		orderXmlSb.append("<totalLogisticsNo></totalLogisticsNo>\n");
		orderXmlSb.append("<subLogisticsNo></subLogisticsNo>\n");
		orderXmlSb.append("<logisticsNo></logisticsNo>\n");
		orderXmlSb.append("<trackNo></trackNo>\n");
		orderXmlSb.append("<trackStatus></trackStatus>\n");
		orderXmlSb.append("<crossFreight></crossFreight>\n");
		orderXmlSb.append("<supportValue></supportValue>\n");
		orderXmlSb.append("<weight>"+storageOrder.getWeight()+"</weight>\n");
		orderXmlSb.append("<netWeight></netWeight>\n");
		orderXmlSb.append("<quantity>"+goodsCount+"</quantity>\n");
		orderXmlSb.append("<deliveryWay></deliveryWay>\n");
		orderXmlSb.append("<transportationWay>4</transportationWay>\n");
		orderXmlSb.append("<shipCode>32</shipCode>\n");
		orderXmlSb.append("<shipName>汽车</shipName>\n");
		orderXmlSb.append("<destinationPort></destinationPort>\n");
		orderXmlSb.append("</OrderPaymentLogistics>\n");
		orderXmlSb.append("</Order>\n");
		return orderXmlSb.toString();
	}

}
